##
# nvnc.py - Created by Timothy Morey on 5/18/2012
#

import sys
import threading
import time

from display_process import *
from libnvn import data_source
from libnvn import logger
from server_process import *

logger.InitLogger('nvn-client.out', 7, 0, 0)

g_Displays = dict()

g_Server = ServerProcess('tessy.umcs.maine.edu', '12345')
#g_Server = ServerProcess('timothy-morey.dnsdynamic.net', '12345')

g_DisplayID = 0


def AddLayer(disp = None, 
             dataset = None, 
             varname = None,
             xdim = None,
             ydim = None,
             tdim = None):
    global g_Displays
    global g_Server

    if disp is None and len(g_Displays) > 0:
        disp = g_Displays.items()[0][1]
    elif not isinstance(disp, DisplayProcess):
        disp = g_Displays[disp]

    if disp is not None:
        datasource = data_source.DataSourceDescriptor()
        if dataset.lower().startswith('http'):
            datasource.Type = data_source.DataSourceTypeOPeNDAP
            datasource.Dataset = dataset
        else:
            datasource.Type = data_source.DataSourceTypeNvnServer
            datasource.Dataset = 'tessy.umcs.maine.edu:12345/' + dataset
        datasource.Varname = varname
        disp.AddLayer(datasource, xdim, ydim, tdim)


def AddMaskedLayer(disp, valuedataset, valuename, maskdataset, maskname):
    global g_Displays
    global g_Server

    if not isinstance(disp, DisplayProcess):
        disp = g_Displays[disp]

    if disp is not None:
        datasource = data_source.DataSourceDescriptor()
        if valuedataset.lower().startswith('http'):
            datasource.Type = data_source.DataSourceTypeOPeNDAP
            datasource.Dataset = valuedataset
        else:
            datasource.Type = data_source.DataSourceTypeNvnServer
            datasource.Dataset = 'tessy.umcs.maine.edu:12345/' + valuedataset
        datasource.Varname = valuename

        masksource = data_source.DataSourceDescriptor()
        if maskdataset.lower().startswith('http'):
            masksource.Type = data_source.DataSourceTypeOPeNDAP
            masksource.Dataset = maskdataset
        else:
            masksource.Type = data_source.DataSourceTypeNvnServer
            masksource.Dataset = 'tessy.umcs.maine.edu:12345/' + maskdataset
        masksource.Varname = maskname

        disp.AddMaskedLayer(datasource, masksource)


def AdjustDisplay(id, x, y, width, height, borderless):
    global g_Displays

    if not isinstance(disp, DisplayProcess):
        disp = g_Displays[disp]

    if disp is not None:
        disp.AdjustWindow(x, y, width, height, borderless)


def Animate(disp):
    global g_Displays

    if not isinstance(disp, DisplayProcess):
        disp = g_Displays[disp]

    if disp is not None:
        t = threading.Thread(target=disp.Animate)
        t.name = 'Animator (' + str(disp.ChattyPort) + ')'
        t.start()


def CloseDisplay(disp):
    global g_Displays

    if not isinstance(disp, DisplayProcess):
        disp = g_Displays[disp]

    if disp is not None:
        disp.CloseDisplay()
        g_Displays.pop(disp.ID)


def CloseDisplays():
    global g_Displays

    for key, value in g_Displays.items():
        value.CloseDisplay()

    g_Displays.clear()


def ConnectDisplay(addr, port):
    global g_Displays
    global g_DisplayID

    id = g_DisplayID
    g_DisplayID += 1

    disp = DisplayProcess(id, addr, str(port))
    g_Displays[id] = disp
    
    return disp


def CreateDisplay(id = None, x = None, y = None, width = None, height = None, borderless = None):
    global g_Displays
    global g_DisplayID
  
    if id is None:
        id = g_DisplayID
        g_DisplayID += 1

    disp = DisplayProcess(id, '127.0.0.1', None,
                          x, y, width, height, borderless)
    g_Displays[id] = disp

    return disp


def PrintDatasetInfo(dataset):
    global g_Server

    schema = g_Server.GetDataSetSchema(dataset)
    print schema


def PrintFrameCounts():
    global g_Displays

    for dispid, disp in g_Displays.items():
        count = disp.GetFrameCount()

        if count is None:
            print dispid, '???'
        else:
            print dispid, count


##########################
# Testy stuff:
##########################

def Test():
    disp = CreateDisplay()
    AddMaskedLayer(disp, 'ex_g10km_m10ka.nc', 'temppabase', 'ex_g10km_m10ka.nc', 'mask')
    #AddLayer(disp, 'ex_g10km_m10ka.nc', 'mask')

def TileHome():
    CreateDisplay(x=    0, y=  0, width=480, height=1100, borderless=True)
    CreateDisplay(x=  480, y=  0, width=480, height=1100, borderless=True)
    CreateDisplay(x=  960, y=  0, width=480, height=1100, borderless=True)
    CreateDisplay(x= 1440, y=  0, width=480, height=1100, borderless=True)

    AddLayer(g_Displays[0], 'ex_g10km_m10ka.nc', 'diffusivity')
    AddLayer(g_Displays[1], 'ex_g10km_m10ka.nc', 'hardav')
    AddLayer(g_Displays[2], 'ex_g10km_m10ka.nc', 'tauc')
    AddMaskedLayer(g_Displays[3], 'ex_g10km_m10ka.nc', 'temppabase', 'ex_g10km_m10ka.nc', 'mask')

def GetMinFrameCount():
    framecount = sys.maxint
    for dispid, disp in g_Displays.items():
        framecount = min(framecount, disp.GetFrameCount())
    return framecount

def Sync():
    global g_Displays

    frame = 0
    while frame < GetMinFrameCount():
        #print 'Drawing frame ' + str(frame)
        for dispid, disp in g_Displays.items():
            disp.SetCurrentFrame(frame)
        frame += 1
        time.sleep(0.1)


def TileWall():
    CreateDisplay(id='top-left', x=0, y=0, width=630, height=590, borderless=True)
    CreateDisplay(id='top-center', x=640, y=0, width=630, height=590, borderless=True)
    CreateDisplay(id='top-right', x=1280, y=0, width=630, height=590, borderless=True)
    '''CreateDisplay(id='bottom-left', x=0, y=600, width=630, height=590, borderless=True)
    CreateDisplay(id='bottom-center', x=640, y=600, width=630, height=590, borderless=True)
    CreateDisplay(id='bottom-right', x=1280, y=600, width=630, height=590, borderless=True)'''

    AddMaskedLayer('top-left', 'ex_g10km_m10ka.nc', 'tauc', 'ex_g10km_m10ka.nc', 'mask')
    AddMaskedLayer('top-center', 'ex_g10km_m10ka.nc', 'temppabase', 'ex_g10km_m10ka.nc', 'mask')
    AddMaskedLayer('top-right', 'ex_g10km_m10ka.nc', 'hardav', 'ex_g10km_m10ka.nc', 'mask')
    '''AddMaskedLayer('bottom-left', 'ex_g10km_m10ka.nc', 'diffusivity', 'ex_g10km_m10ka.nc', 'mask')
    AddMaskedLayer('bottom-center', 'ex_g10km_m10ka.nc', 'cbase', 'ex_g10km_m10ka.nc', 'mask')
    AddMaskedLayer('bottom-right', 'ex_g10km_m10ka.nc', 'csurf', 'ex_g10km_m10ka.nc', 'mask')'''



# HACK: For debugging via Visual Studio, jump into the python REPL loop before
# the script exits.  This allows us to use the VS debugger to debug our code
# from the interactive prompt.
if __name__ == '__main__' and sys.platform == 'win32':
    import code

    try:
        code.InteractiveConsole(locals=globals()).interact()
    except SystemExit:
        pass

